package com.pan.hisystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pan.hisystem.config.JwtTokenUtil;
import com.pan.hisystem.mapper.RoleMapper;
import com.pan.hisystem.mapper.UserRoleMapper;
import com.pan.hisystem.pojo.*;
import com.pan.hisystem.mapper.UserMapper;
import com.pan.hisystem.service.IRegistrationService;
import com.pan.hisystem.service.IUserRoleService;
import com.pan.hisystem.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author qingyang
 * @since 2022-03-02
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Value("${jwt.tokenHead}")//头部信息通过value注解去拿
    private String tokenHead;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private IUserRoleService userRoleService;
    @Autowired
    private IRegistrationService registrationService;
    @Autowired
    private RoleMapper roleMapper;

    @Override
    public RespBean login(String username, String password, String code, HttpServletRequest request) {
        String msg=(String) request.getSession().getAttribute("captcha");
        //equalsIgnoreCase不考虑大小写
        if( !msg.equalsIgnoreCase(code)){
            return RespBean.error("验证码错误");
        }
        UserDetails userDetails=userDetailsService.loadUserByUsername(username);//UserDetails提供存储信息登录的对象
        //passwordEncoder.matches(加密前密码（输入的密码），加密后密码（数据库中加密的密码）)
        if(userDetails==null||!passwordEncoder.matches(password,userDetails.getPassword())){
            return RespBean.error("输入账号或密码错误");
        }
        if(!userDetails.isEnabled()){
            return RespBean.error("账号被禁用，请联系管理员");
        }
        //更新security登录对象
        UsernamePasswordAuthenticationToken authenticationToken=new UsernamePasswordAuthenticationToken(userDetails
                ,null,userDetails.getAuthorities());
        //将登录对象放到Security的全局里，更新
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);//有了这一步才能使用Principal进行验证
        //生成token
        String token=jwtTokenUtil.generateToken(userDetails);//生成令牌
        Map<String,String> tokenMap=new HashMap<>();
        tokenMap.put("token",token);
        tokenMap.put("tokenHead",tokenHead);
        return RespBean.success("登录成功",tokenMap);

    }

    /**
     * 获取操作员角色
     * @param uid
     */
    @Override
    public List<Role> getUserRoles(Integer uid) {
        return  userMapper.getUserRoles(uid);
    }

    /**
     * 获取所有操作员（有角色）
     * @return
     */
    @Override
    public List<User> getUsersWithRoles() {
        return userMapper.getUsersWithRoles();
    }

    /**
     * 更新操作员及其角色
     * @param user
     * @return
     */
    @Override
    @Transactional
    public RespBean updateUserWithRole(User user) {
        List<Role> roleList= user.getRoles();
        List<Integer> rids=new ArrayList<>();
        for (Role role : roleList) {
            rids.add(role.getId());
        }
        int i=0;
        if(userMapper.updateById(user)==1){
            if(userRoleService.list(new QueryWrapper<UserRole>().eq("uid", user.getId()))!=null){
                userRoleService.remove(new QueryWrapper<UserRole>().eq("uid", user.getId()));
                i=userRoleMapper.updateUserWithRole(user.getId(),rids,LocalDateTime.now());
            }
            else{
                i=userRoleMapper.updateUserWithRole(user.getId(),rids,LocalDateTime.now());
            }
            if(i==rids.size()){
                return RespBean.success("更新成功");
            }
            }

        return RespBean.error("更新失败");
    }

    /**
     * 添加操作员及角色
     * @param user
     * @return
     */
    @Override
    @Transactional
    public RespBean addUserWithRole(User user) {
        List<Role> roleList= user.getRoles();
        List<Integer> rids=new ArrayList<>();
        for (Role role : roleList) {
            rids.add(role.getId());
        }
        int i=0;
        if(userMapper.insert(user)==1){
            i=userRoleMapper.updateUserWithRole(user.getId(),rids,LocalDateTime.now());
        }
        if(i==rids.size()){
            return RespBean.success("更新成功");
        }
        return RespBean.error("更新失败");

    }

    /**
     * 删除操作员及角色
     * @param id
     * @return
     */
    @Override
    @Transactional
    public RespBean deleteUser(Integer id) {
        if(userMapper.deleteById(id)==1){
            userRoleMapper.delete(new QueryWrapper<UserRole>().eq("uid",id));
            return RespBean.success("删除成功");
        }
        return RespBean.error("删除失败");
    }

    /**
     * 获取角色为医生的操作员
     * @param did
     * @param tid
     * @param mid
     * @return
     */
    @Override
    public List<User> getUserWithDoctor(Integer did, Integer tid, String mid) {
        List<User> userList =userMapper.getUserWithDoctor(did,tid);
        Registration registration=registrationService.getOne(new QueryWrapper<Registration>()
                .eq("mid",mid)
                .eq("enabled",false)
                .eq("back_status",false));
        if(registration!=null){
            userList.removeIf(user -> user.getId().equals(registration.getUid()));//去掉集合某患者里有挂号记录但未完成就诊的医师
        }
        User user=(User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        for (User user1 : userList) {
            System.out.println(user1.toString());
            user1.setRoles(user.getRoles());
        }
        return userList;
    }

    /**
     * 根据姓名获取操作员
     * @param name
     * @return
     */
    @Override
    public List<User> getUserByName(String name) {
        return userMapper.getUserByName(name);
    }

    /**
     * 根据用户id查询其对应的角色列表
     * @param id
     * @return
     */
    @Override
    public List<Role> getRoles(Integer id) {
        return roleMapper.getRoles(id);
    }

    /**
     * 更新用户密码
     * @param oldPass
     * @param pass
     * @param userId
     * @return
     */
    @Override
    public RespBean updatePassword(String oldPass, String pass, Integer userId) {
        User user = userMapper.selectById(userId);
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        if (encoder.matches(oldPass,user.getPassword())){
            user.setPassword(encoder.encode(pass));
            int i = userMapper.updateById(user);
            if (i == 1){
                return RespBean.success("更新成功");
            }
        }
        return RespBean.error("更新失败");
    }

}
